package com.example.wendao.viewmodel;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.paging.PagedList;

import com.example.wendao.common.AsyncExecutor;
import com.example.wendao.common.PageUtils;
import com.example.wendao.model.entity.Fans;
import com.example.wendao.model.entity.User;
import com.example.wendao.model.service.FansService;
import com.example.wendao.model.service.ForumService;
import com.example.wendao.model.service.NewsService;
import com.example.wendao.model.service.UserService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 关于用户的数据和操作的封装：包括了关注部分和用户信息部分
 */
public class UserViewModel extends ViewModel {

    private FansService fansService;

    private UserService userService;

    private ForumService forumService;

    private NewsService newsService;


    private final static int MAX_USERNAME_SIZE = 10;

    private final static int MAX_PASSWORD_SIZE = 12;

    private final static int MIN_PASSWORD_SIZE = 6;


    /**
     *  所有的用户
     */
    private LiveData<PagedList<User>> allUser;

    /**
     *  当前用户
     */
    private User currentUser;

    /**
     *  当前用户的LiveData形式
     */
    private MutableLiveData<User> liveCurrentUser = new MutableLiveData<>();

    /**
     *  当前用户的全部粉丝
     */
    private LiveData<PagedList<User>> allFans;

    /**
     *  当前用户的所有关注
     */
    private LiveData<PagedList<User>> allFollowers;

    public LiveData<PagedList<User>> findSomeUsersByUserIds(String sql) {
        return new PageUtils<User>()
                .buildLivePagedList(userService.findSomeUsersByUserIds(sql));
    }

    {
        fansService = new FansService();
        userService = new UserService();
        allUser = new PageUtils<User>().buildLivePagedList(userService.queryAllUser());
    }

    /**
     *  通过用户名模糊查询，获得LiveData形式的用户分页列表
     * @param username  需要模糊查询的用户名
     * @return          查询结果为分页列表形式的用户列表
     */
    public LiveData<PagedList<User>> getUsersByName(String username){
        return new PageUtils<User>().buildLivePagedList(userService.findUserByName(username));
    }

    /**
     *  返回全部的用户
     * @return 全部的用户
     */
    public LiveData<PagedList<User>> getAllUser(){
        return allUser;
    }


    /**
     *
     * @param newsId    新闻id
     * @return          该新闻是不是被已经被当前用户点赞
     */
    public boolean newsIsAgree(int newsId){
        return new HashSet<>(getCurrentAnewsId()).contains(newsId);
    }

    /**
     *
     * @param forumId   论坛id
     * @return          该论坛是不是已经被当前用户点赞
     */
    public boolean forumIsAgree(int forumId){
        return new HashSet<>(getCurrentAforumId()).contains(forumId);
    }


    public List<Integer> getCurrentCnewsId(){

        List<Integer> integers = new ArrayList<>();
        String[] strs = currentUser.getCnewsId().split(",");
        if (!strs[0].equals("")){
            for (int i = 0; i < strs.length; i++){
                integers.add(Integer.valueOf(strs[0]));
            }
        }
        return integers;
    }

    public List<Integer> getCurrentCforumId(){
        List<Integer> integers = new ArrayList<>();
        String[] strs = currentUser.getCforumId().split(",");
        if (!strs[0].equals("")){
            for (int i = 0; i < strs.length; i++){
                integers.add(Integer.valueOf(strs[0]));
            }
        }
        return integers;
    }

    public List<Integer> getCurrentAnewsId(){
        List<Integer> integers = new ArrayList<>();
        if (currentUser != null){
            String[] strs = currentUser.getAnewsId().split(",");
            if (!strs[0].equals("")){
                for (int i = 0; i < strs.length; i++){
                    integers.add(Integer.valueOf(strs[0]));
                }
            }
        }
        return integers;
    }


    public List<Integer> getCurrentAforumId(){
        List<Integer> integers = new ArrayList<>();
        if (currentUser != null){
            String[] strs = currentUser.getAforumId().split(",");
            if (!strs[0].equals("")){
                for (int i = 0; i < strs.length; i++){
                    integers.add(Integer.valueOf(strs[0]));
                }
            }
        }
        return integers;
    }

    public List<Integer> getCurrentBnewsId(){
        List<Integer> integers = new ArrayList<>();
        if (currentUser != null){
            String[] strs = currentUser.getBnewsId().split(",");
            if (!strs[0].equals("")){
                for (int i = 0; i < strs.length; i++){
                    integers.add(Integer.valueOf(strs[0]));
                }
            }
        }
        return integers;
    }

    public List<Integer> getCurrentBforumId(){
        List<Integer> integers = new ArrayList<>();
        if (currentUser != null){
            String[] strs = currentUser.getBforumId().split(",");
            if (!strs[0].equals("")){
                for (int i = 0; i < strs.length; i++){
                    integers.add(Integer.valueOf(strs[0]));
                }
            }
        }
        return integers;
    }

    public List<Integer> getCurrentUserGoods(){
        List<Integer> integers = new ArrayList<>();
        if (currentUser != null){
            String[] strs = currentUser.getUserGoods().split(",");
            if (!strs[0].equals("")){
                for (int i = 0; i < strs.length; i++){
                    integers.add(Integer.valueOf(strs[0]));
                }
            }
        }
        return integers;
    }


    /**
     * 通过用户ID   查询出唯一的用户
     * @param id    用户id
     * @return      根据id查询出来的对应用户
     */
    public User getUserById(int id){
        return new AsyncExecutor<User>().submit(() -> userService.findUserById(id));
    }

    /**
     *  添加一个用户
     * @param users 要插入的用户
     * @return      返回值为 1
     */
    public int addSomeUser(User... users){
        return new AsyncExecutor<Integer>().submit(()-> userService.insertUser(users));
    }

    /**
     *  删除一个用户
     * @param user  要删除的一个用户
     * @return      返回值为 1
     */
    public int delUser(User user){
        return new AsyncExecutor<Integer>().submit(() -> userService.delUser(user));
    }


    /**
     *  新用户注册
     * @param user  请求注册的用户
     * @return      通过注册验证为 true 未通过为 false
     */
    public boolean register(User user) {
        new AsyncExecutor<>().execute(() -> userService.register(user));
        return true;
    }

    /**
     *  对一个用户对象的用户名和密码进行验证
     * @param user  用户对象
     * @return      用户信息是否有效，有效为true，无效为false
     */
    private boolean verifyUser(User user) {
        return user.getUsername() == null
                || user.getUsername().equals("")
                || user.getUsername().toCharArray().length > MAX_USERNAME_SIZE
                || user.getPassword() == null
                || user.getPassword().equals("")
                || user.getPassword().toCharArray().length > MAX_PASSWORD_SIZE
                || user.getPassword().toCharArray().length < MIN_PASSWORD_SIZE;
    }


    /**
     * 根据用户名和密码获取对应的用户
     * @param username  要登录的用户名
     * @param password  要登录的密码
     * @return          登录成功返回User对象，登录失败返回null
     */
    public User login(String username, String password) {
        currentUser = new AsyncExecutor<User>().submit(()-> userService.login(username, password));
        liveCurrentUser.setValue(currentUser);
        return currentUser;
    }

    /**
     * 获取当前登录的用户
     * @return 当前登录的用户，如果未登录返回null
     */
    public User getCurrentUser(){
        return currentUser;
    }

    /**
     * 返回LiveData形式的当前用户
     * @return 当前登录的用户的LiveData形式
     */
    public LiveData<User> getLiveCurrentUser(){
        return liveCurrentUser;
    }

    public void setCurrentUser(User user){
        liveCurrentUser.setValue(user);
        currentUser = user;
    }

    /**
     *
     * @param username  要检查是否存在的用户名
     * @return          如果用户名存在 返回 true，不存在 返回 false
     */
    public boolean checkUsername(String username){
        return new AsyncExecutor<Boolean>().submit(() -> userService.findUserName(username) == 1);
    }

    /**
     * 获取当前是否有用户登录
     * @return 返回当前用户是否登录 登录返回true 未登录返回false
     */
    public boolean userLoggedIn() {
        return getCurrentUser() != null;
    }

    /**
     *  退出登录，使当前用户为null，ViewModel中用户可以访问的数据清空
     */
    public void logout() {
        currentUser = null;
        allFans = null;
        allFollowers = null;
    }

    /**
     * 更新用户的信息
     * @param user  需要更新信息的用户对象
     */
    public void updateUser(User user){
        new AsyncExecutor<>().execute(() -> userService.updateUser(user));
    }

    /**
     * 当前用户对一个用户进行关注
     * @param beFollower    要关注的用户
     * @return              关注操作结果 成功返回true 用户为空返回false
     */
    public boolean follow(User beFollower){
        return new AsyncExecutor<Boolean>().submit(() -> follow(currentUser, beFollower));
    }

    /**
     * 一个用户对另一个用户进行关注
     * @param me    当前用户，也就是关注者
     * @param him   要关注的用户，也就是被关注者
     * @return      是否关注成功
     */
    private boolean follow(User me, User him) {
        if (me == null || userService.findUserById(me.getUserId()) == null ||
                him == null || userService.findUserById(him.getUserId()) == null)
            return false;
        Fans fans = new Fans(0, him.getUserId(), me.getUserId(),
                fansService.queryIsFollow(me.getUserId(), him.getUserId()) == null ? 0 : 1);
        new AsyncExecutor<>().execute(() -> fansService.followEachOther(me.getUserId(), him.getUserId()));
        new AsyncExecutor<>().execute(() -> fansService.follow(fans));
        return true;
    }

    /**
     * 获取当前用户对另一个用户的关注状态
     * @param other     除当前用户外的某一个用户实例
     * @return          当前用户是否关注了该用户
     */
    public boolean isFollowed(User other) {
        return queryIsFollow(other.getUserId(), currentUser.getUserId()) != null;
    }

    /**
     *
     * @param beFollowerId  被关注者ID
     * @param followerId    关注者ID
     * @return              如果有对应的关注关系则返回Fans对象
     */
    private Fans queryIsFollow(int beFollowerId, int followerId) {
        return new AsyncExecutor<Fans>()
                .submit(() -> fansService.queryIsFollow(beFollowerId, followerId));
    }

    /**
     *
     * @param beFollowers   要关注的用户列表，可以同时关注多个用户
     */
    public void followSome(User... beFollowers){
        List<Fans> fans = new ArrayList<>();
        for (User user : beFollowers) {
            Fans fan = new Fans();
            fan.setFollowerId(currentUser.getUserId());
            fan.setBeFollowerId(user.getUserId());
            fan.setFollowEachOther(queryIsFollow(currentUser.getUserId(), user.getUserId()) == null ? 0 : 1);
            fans.add(fan);
        }
        Fans[] fans1 = new Fans[fans.size()];
        insertFans(fans.toArray(fans1));
    }

    /**
     *
     * @param fans  要插入的粉丝序列
     */
    private void insertFans(Fans... fans) {
        new AsyncExecutor<>().execute(() -> fansService.insertFans(fans));
    }

    /**
     *
     * @return  当前用户的全部粉丝
     */
    public LiveData<PagedList<User>> getAllFans() {
        return allFans = allFans == null ? new PageUtils<User>()
                .buildLivePagedList(fansService.queryAllFans(currentUser.getUserId())) : allFans;
    }

    /**
     *
     * @return  当前用户的全部关注
     */
    public LiveData<PagedList<User>> getAllFollowers() {
        return allFollowers = allFollowers == null ? new PageUtils<User>()
                .buildLivePagedList(fansService.queryAllFollower(currentUser.getUserId())) : allFollowers;
    }

}
